﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web;
using CGT.API.Models;
using CGT.API.Models.BaiduAI;
using Newtonsoft.Json.Linq;
using OF.Utility;
using OF.Utility.Logging;

namespace CGT.API.Common
{
    /// <summary>
    /// 百度AI
    /// </summary>
    public class BaiduAI
    {
        // 调用getAccessToken()获取的 access_token建议根据expires_in 时间 设置缓存

        // APPID
        private static string appId = ConfigHelper.GetValue("BaiduAI.AppID");
        // 百度云中开通对应服务应用的 API Key 建议开通应用的时候多选服务
        private static String clientId = ConfigHelper.GetValue("BaiduAI.APIKey");
        // 百度云中开通对应服务应用的 Secret Key
        private static String clientSecret = ConfigHelper.GetValue("BaiduAI.SecretKey");

        /// <summary>
        /// 人脸对比
        /// </summary>
        /// <param name="imgpath1">图片1路径</param>
        /// <param name="imgpath2">图片2路径</param>
        /// <returns></returns>

        public string face_facecompare(string imgpath1, string imgpath2)
        {
            var img1 = FileToBase64(imgpath1);
            var img2 = FileToBase64(imgpath2);
            var client = new Baidu.Aip.Face.Face(clientId, clientSecret);
            var faces = new JArray
            {
                new JObject
                {
                    {"image",img1},
                    {"image_type", "BASE64"},
                    {"face_type", "LIVE"},
                    {"quality_control", "NONE"},
                    {"liveness_control", "NONE"},
                },
                new JObject
                {
                    {"image", img2},
                    {"image_type", "BASE64"},
                    {"face_type", "LIVE"},
                    {"quality_control", "NONE"},
                    {"liveness_control", "NONE"},
                }
            };
            var result = new JObject();
            try
            {
                result = client.Match(faces);
            }
            catch (Exception ex)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("face_facecompare;");
                sb.AppendLine(ex.Message);
                sb.AppendLine(ex.StackTrace);
                sb.AppendLine(ex.Source);
                Log4netLog.Debug(sb.ToString());
            }
            return result.ToString();
        }
        public ResultData<FaceCompareModel> ParseFaceCompareResult(string resultStr)
        {
            ResultData<FaceCompareModel> result = new ResultData<FaceCompareModel>();
            FaceCompareModel model = new FaceCompareModel();
            result.data = model;
            result.status = 0;
            StringBuilder sb = new StringBuilder();
            //转json失败则直接返回空对象
            try
            {
                JObject json = JObject.Parse(resultStr);
                var words_result = json["result"];
                if (words_result.Type != JTokenType.Null && words_result.HasValues)
                {
                    sb.AppendLine((string)words_result["score"]);
                    var score = EConvert.ToFloat((string)words_result["score"]);
                    model.Similarity = score;
                }
                else
                {
                    result.status = -1;
                    result.message = "图片不符合规范，请重试";
                }
            }
            catch (Exception ex)
            {

                sb.AppendLine("ParseFaceCompareResult转换;");
                sb.AppendLine(ex.Message);
                sb.AppendLine(ex.StackTrace);
                sb.AppendLine(ex.Source);
                Log4netLog.Debug(sb.ToString());
                result.status = -1;
                result.message = "图片不符合规范，请重试";
            }
            return result;
        }
        /// <summary>
        /// 识别并且获取身份证信息
        /// </summary>
        /// <param name="filePath">身份证地址</param>
        /// <param name="cardType">身份证正反面 0:正面 1：反面</param>
        /// <returns></returns>

        /// <summary>
        /// 身份证识别
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="cardType"></param>
        /// <returns></returns>
        public string ocr_idcardocr(string filePath, string cardType)
        {
            var client = new Baidu.Aip.Ocr.Ocr(clientId, clientSecret);
            var image = File.ReadAllBytes(filePath);
            var idCardSide = cardType == "0" ? "front" : "back";
            var strInfo = "";
            // 调用身份证识别
            try
            {
                // 带参数调用身份证识别
                var result = client.Idcard(image, idCardSide);
                var arrResult = result.ToString();
                strInfo = arrResult;
            }
            catch (Exception ex)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine(ex.Message);
                sb.AppendLine(ex.StackTrace);
                sb.AppendLine(ex.Source);
                Log4netLog.Debug(sb.ToString());
            }
            return strInfo;
        }

        /// <summary>
        /// 语音识别
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <returns>返回语音识别的字符串</returns>
        public JObject aai_asr(string path)
        {
            var client = new Baidu.Aip.Speech.Asr(appId, clientId, clientSecret);
            var data = File.ReadAllBytes(path);
            // 可选参数
            var options = new Dictionary<string, object>
             {
                {"dev_pid", 1536}
             };

            try
            {
                client.Timeout = 120000; // 若语音较长，建议设置更大的超时时间. ms
                return client.Recognize(data, "pcm", 16000, options);

            }
            catch (Exception ex)
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine(ex.Message);
                sb.AppendLine(ex.StackTrace);
                sb.AppendLine(ex.Source);
                Log4netLog.Debug(sb.ToString());
            }
            return null;
        }

        /// <summary>
        /// 请求获取accesstoken签名
        /// </summary>
        /// <returns></returns>
        public string getAccessToken()
        {
            String authHost = "https://aip.baidubce.com/oauth/2.0/token";
            HttpClient client = new HttpClient();
            List<KeyValuePair<String, String>> paraList = new List<KeyValuePair<string, string>>();
            paraList.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
            paraList.Add(new KeyValuePair<string, string>("client_id", clientId));
            paraList.Add(new KeyValuePair<string, string>("client_secret", clientSecret));

            HttpResponseMessage response = client.PostAsync(authHost, new FormUrlEncodedContent(paraList)).Result;
            String result = response.Content.ReadAsStringAsync().Result;
            Console.WriteLine(result);
            JObject json = JObject.Parse(result);
            var accessToken = (string)json["access_token"];
            return accessToken;
        }

        /// <summary>
        /// 文件读取成base64
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        protected string FileToBase64(string path)
        {
            byte[] inArray = File.ReadAllBytes(path);
            string str = Convert.ToBase64String(inArray);
            return str;
        }

        /// <summary>
        /// URL编码
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public string UrlEncode(string str)
        {
            StringBuilder sb = new StringBuilder();
            byte[] byStr = System.Text.Encoding.UTF8.GetBytes(str); //默认是System.Text.Encoding.Default.GetBytes(str)
            for (int i = 0; i < byStr.Length; i++)
            {
                sb.Append(@"%" + Convert.ToString(byStr[i], 16));
            }

            return (sb.ToString());
        }

        ///// <summary>
        ///// 调用示例
        ///// </summary>
        ///// <returns></returns>
        //public IdcardOCRModel Demo()
        //{
        //    var path = @"C:\Project\self\C#\base\30\id1.jpg";
        //    var cardType = "0";//0正面1反面
        //    var strResult = ocr_idcardocr(path, cardType);
        //    //转实体
        //    var model = ParseIdCardResult(strResult, cardType);
        //    model.data.ImgageName = GetFileName(path);
        //    return model.data;
        //}

        /// <summary>
        ///  OCR识别结果字符串转model
        /// </summary>
        /// <param name="resultStr">接口返回结果字符串</param>
        /// <param name="type">类别 0正面1反面</param>
        /// <returns></returns>
        public ResultData<IdcardOCRModel> ParseIdCardResult(string resultStr, string type)
        {
            ResultData<IdcardOCRModel> result = new ResultData<IdcardOCRModel>();
            IdcardOCRModel model = new IdcardOCRModel();
            result.data = model;
            result.status = 0;
            //转json失败则直接返回空对象
            try
            {
                JObject json = JObject.Parse(resultStr);
                var words_result = json["words_result"];
                if (words_result.Type != JTokenType.Null && words_result.HasValues)
                {
                    if (type == "0")
                    {
                        model.Address = (string)words_result["住址"]["words"];
                        model.Birth = (string)words_result["出生"]["words"];
                        model.Name = (string)words_result["姓名"]["words"];
                        model.Id = (string)words_result["公民身份号码"]["words"];
                        model.Nation = (string)words_result["民族"]["words"];
                        model.Sex = (string)words_result["性别"]["words"];
                    }
                    else
                    {
                        model.Authority = (string)words_result["签发机关"]["words"];
                        model.ValidDate = (string)words_result["失效日期"]["words"];
                    }
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("IDcard转换:" + resultStr);
                    Log4netLog.Debug(sb.ToString());
                    result.status = -1;
                    result.message = "图片不符合规范，请重试";
                }
            }
            catch (Exception ex)
            {
                result.status = -1;
                StringBuilder sb = new StringBuilder();
                sb.AppendLine(string.Format("IDcard转换抛出异常:{0}", resultStr));
                result.message = "图片不符合规范，请重试";
            }
            return result;
        }

        /// <summary>
        /// 语音识别转model
        /// </summary>
        /// <param name="result"></param>
        /// <returns></returns>
        public ResultData<ASRModel> ParseASRResult(JObject result)
        {
            ResultData<ASRModel> rt = new ResultData<ASRModel>();
            ASRModel model = new ASRModel();
            rt.data = model;
            
            var arrResult = result["result"];
            if (arrResult.Type != JTokenType.Null && arrResult.HasValues)
            {
                var array = arrResult.ToArray();
                if (array.Length > 0)
                {
                    model.Text = array[0].ToString();
                }
                rt.message = result["err_msg"].ToString();
            }
            else
            {
                StringBuilder sb = new StringBuilder();
                sb.AppendLine("语音识别转换:" + arrResult.ToString());
                Log4netLog.Debug(sb.ToString());
            }
            return rt;
        }

        /// <summary>
        /// 获取文件名称
        /// </summary>
        /// <param name="fullFileName"></param>
        /// <returns></returns>
        protected string GetFileName(string fullFileName)
        {
            int idx = fullFileName.LastIndexOf("\\");
            return fullFileName.Substring(idx + 1);
        }

    }
}